module concat #(
    parameter int unsigned WIDTH = 32,
    parameter int unsigned P_CH  = 16,
    parameter int unsigned N_CH0 = 64,
    parameter int unsigned N_CH1 = 64
) (
    input  logic                  clk,
    input  logic                  rst_n,
    input  logic [P_CH*WIDTH-1:0] in0_data,
    input  logic                  in0_valid,
    output logic                  in0_ready,
    input  logic [P_CH*WIDTH-1:0] in1_data,
    input  logic                  in1_valid,
    output logic                  in1_ready,
    output logic [P_CH*WIDTH-1:0] out_data,
    output logic                  out_valid,
    input  logic                  out_ready
);

    localparam int unsigned TOTAL_CH = (N_CH0 + N_CH1) / P_CH;
    localparam int unsigned MID_CH = N_CH0 / P_CH;
    logic                          in_valid;
    logic [             WIDTH-1:0] in_data;
    logic [$clog2(TOTAL_CH+1)-1:0] cnt;
    logic                          sel;

    assign sel       = (cnt >= MID_CH);
    assign in_valid  = sel ? in1_valid : in0_valid;
    assign in_data   = sel ? in1_data : in0_data;
    assign in0_ready = out_ready && !sel;
    assign in1_ready = out_ready && sel;

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt <= '0;
        end else begin
            if (in_valid && out_ready) begin
                if (cnt == TOTAL_CH - 1) begin
                    cnt <= '0;
                end else begin
                    cnt <= cnt + 1;
                end
            end
        end
    end

endmodule
